Industrial controllers are special purpose computers used for controlling industrial processes in manufacturing equipment. Under the direction of a stored program, an industrial controller examines a series of inputs reflecting the status of a controlled process and changes outputs affecting control of the process.
Industrial controllers are frequently programmed in a "relay ladder" language where instructions are represented graphically by "contacts" and "coils" of virtual relays connected and arranged in ladder-like rungs. This relay ladder language, with its input contacts and output coils, reflects the emphasis in industrial control on the collection and transmission of large numbers of inputs and outputs. The relay ladder language also reflects the fact that most industrial control is "real time." That is, an ideal industrial controller behaves as if it were composed of multiple relays connected in parallel ladder rungs to produce outputs in essentially instantaneous response to changing inputs.
In reality, however, the parallel relay-like structure of a ladder diagram program is, in fact, executed sequentially one step at a time. The appearance of parallel operation is obtained by employing an extremely fast processor in the execution of the sequential program.
During the industrial control process, an industrial control processor must perform many different tasks in order to support an industrial process. As many control processes are extremely complex, normally a processor receives a plurality of tasks for concurrent performance. Thus, most processors include a scheduler to store pending tasks while an active task is performed.
The scheduling of several distinct tasks in a conventional computing environment may be undertaken through a number of different timing schemes. For example, a time sharing arrangement in which tasks are assigned priorities and high priority tasks cause the suspension of lower priority tasks for an indefinite period of time may be employed.
In this type of scheme, priority can be based on a number of different characteristics including estimated execution time of the task, estimated amount of I/O activity needed to complete the task, the tasks current resource allotment, the amount of total waiting time, and how important task completion is to the overall industrial operation being controlled.
Another approach used in conventional computing is that of time slicing where each task is given a fixed slice of the central processor's time on a round-robin basis. This approach assures that each task receives a predictable portion of the processor time.
Yet another alternative is a prioritized round-robin queue in which high priority tasks are given relatively larger slices of the central processors time than low priority tasks on a round-robin basis. This approach assures that high priority tasks are performed quickly but that low priority tasks are eventually performed.
In priority-based time sharing schemes, task performance switching can be either preemptive or non-preemptive. Where switching is non-preemptive, if a process arrives with higher priority than the running process, it must wait until the running process relinquishes the processor. When preemption is permitted, a higher priority arrival interrupts the running process's execution and takes control of the processor itself. The preempted process is returned to a pending queue.
In complex control schemes, various tasks of similar importance are often assigned identical priority, tasks sharing the same priority being performed on a round-robin basis. For example, program supporting requests, user background routines, and system support routines, might all share a level 1 priority and share processing resources in a time-slice, round-robin manner. In such a system, once a task begins to run, it is only stopped when it places itself in an in-active state to wait for some event or when a higher priority task needs to run.
In addition to controlling an industrial operation, typical industrial controllers provide means whereby one or more operators can analyze, edit, or search stored programs. This ability to demand and perform operator requests is a requirement for most industrial controllers. For example, where the process prescribed by a ladder diagram is not precisely tuned to specific controlled equipment, or where a new piece of equipment is added to the controlled equipment after the ladder diagram is entered, an operator must have some means to edit the program.
Many schedulers are programmed to queue all requests by operators for ladder diagram program monitoring, searching, and editing, to a single program support task forming a linked list for sequential first-in-first-out (FIFO) processing. Other system requests are often grouped in similar tasks for FIFO processing.
Unfortunately, while sequential execution maintains the integrity of program files, where such execution is required, no other monitor, search or edit operations can occur until an active request is completely performed.
For example, where one user tries to do an edit or a program search while another user is performing a program search operation, the edit or second search request is queued until the first search is completed. Where the first search is long, the second search request or edit may be queued for many minutes. This despite the fact that the second search or edit might only require a few milliseconds of processor time to perform. For this reason, sequential execution of requests within a single task have become problematic in many operating systems. While such delays are undesirable in completion of any request, they are particularly inconvenient in the case of monitor, search, and edit requests where a human operator must wait for request results.
One way to overcome such delays would be to provide a task based preemptive second level of priority, the highest priority within the task being given to the request having the shortest remaining operating time. Thus, when a short request is queued, that request would take priority over all long search, monitor, or edit request queued or being performed.
Another possible solution would be to create a separate priority for each task, giving each request within a task identical priority and allowing the requests to operate on a time slice round-robin basis. For example, each request might be given 0.2 msec of operating time before being preempted and re-queued to await another time slice after the other requests are each processed for 0.2 msec each.
Unfortunately, both of these approaches require a large amount of memory to store state information relating to interrupted requests. Where a long search request is preempted, in addition to storing request identifying information, the system must also store detailed data identifying the location of the file being searched and the interrupt point in the file. Similar information must be stored when either an edit or monitor request is interrupted.
Because industrial processes are extremely complex, system memory is already overburdened in many operating systems. Therefore, queuing schemes that require large amounts of dedicated memory are usually not employed. Instead, most requests within a given task are processed sequentially and, regardless of how long or short a request is, it must wait in the linked list until requests before it are completed.
In addition, where a task internal priority scheme is adopted in which high-priority is granted to the request having the shortest remaining operating time, requests requiring long periods for completion theoretically may never be processed. Moreover, a "time to completion" based priority scheme would be unworkable as the time required to complete edit and search requests cannot be determined prior to performance.
Thus, it would be advantageous to have an operating system wherein short monitor, search, and edit requests could be performed quickly without requiring large amounts of memory for storing state information corresponding to re-queued requests.